package com.atguigu.shirolearn.shiro;

import com.atguigu.shirolearn.bean.User;
import com.atguigu.shirolearn.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import javax.sound.midi.SoundbankResource;

public class UserRealm extends AuthorizingRealm {

    @Autowired
    UserService userService;

    /**
     * 执行授权逻辑
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //给资源进行授权
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        /*
        数据库查询用户权限，并添加
         */
        //1.获取当前用户
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipal();  //这里获取的principal是doGetAuthenticationInfo方法中返回的对象中第一个参数
        User cUser = userService.getUserById(user.getId());
        //2.添加权限
        info.addStringPermission(cUser.getPerms());
        return info;
    }

    /**
     * 执行认证逻辑
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken   ) throws AuthenticationException {

        /*
        shiro判断用户名和密码
         */


        //1.判断用户名
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        /*
        如何判断要不要到数据库去取数据呢，也就是如何判断这个数据是来自用户输入还是redis，如果来自redis，应该不走这里，直接登录
         */
        User user = userService.getUserByName(token.getUsername());
        System.out.println("访问数据库");

        if (user==null) {
            //用户名不存在
            return null;  //shiro 底层会跑出UNknowAccountException
        }

        //2.判断密码
        /**
         * SimpleAuthenticationInfo第一个参数为传递给login controller的参数，第三个参数为shiro的名字
         */
        return new SimpleAuthenticationInfo(user, user.getPassword(), "");

    }
}
